﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Bzzb.Model;
using FreeSql.Internal.Model;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Core.Extension;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OfficeOpenXml;

namespace Bzzb.Controllers
{
    public class ToolController : BaseController
    {
        private readonly IWebHostEnvironment _env;
        private readonly IConfiguration _configuration;
        private readonly ILogger<ToolController> _logger;
        public ToolController(ILogger<ToolController> logger, IFreeSql fsql, IConfiguration configuration, IWebHostEnvironment env) : base(fsql)
        {
            this._env = env;
            this._logger = logger;
            this._configuration = configuration;
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Index([FromForm] string content, [FromForm] int pageIndex = 1, [FromForm] int pageSize = 10)
        {
            DynamicFilterInfo dyfilter = JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
{
  'Logic' : 'And',
  'Filters' :
  [
    {
      'Field' : 'name',
      'Operator' : 'Contains',
      'Value' : '" + content + @"',
    }
  ]
}
");
            List<Tool> tools = await _fsql.Select<Tool>().WhereDynamicFilter(dyfilter).Count(out var total).Page(pageIndex, pageSize).ToListAsync();
            _logger.LogInformation(_fsql.Select<Tool>().WhereDynamicFilter(dyfilter).Page(pageIndex, pageSize).ToSql());
            JObject data = new JObject();
            data.Add("total", total);
            data.Add("list", JArray.FromObject(tools));
            return RenderJson(data: data);
        }

        /// <summary>
        /// 获取所有未使用的工具
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
//        [HttpPost]
//        public async Task<IDictionary<string, Object>> GetAllUnusedTools([FromForm] string content)
//        {
//            DynamicFilterInfo dyfilter = JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
//{
//  'Logic' : 'And',
//  'Filters' :
//  [
//    {
//      'Field' : 'name',
//      'Operator' : 'Contains',
//      'Value' : '" + content + @"',
//    }
//  ]
//}
//");
//            List<Tool> tools = await _fsql.Select<Tool>().Where(t => t.IsUsed == 0).WhereDynamicFilter(dyfilter).ToListAsync();
//            _logger.LogInformation(_fsql.Select<Tool>().Where(t => t.IsUsed == 0).WhereDynamicFilter(dyfilter).ToSql());
//            return RenderJson(data: tools);
//        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Save([FromForm] Tool tool)
        {
            long id = await _fsql.Insert(tool).ExecuteIdentityAsync();
            tool.Id = id;

            return RenderJson(data: tool);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Delete([FromForm] long id) {
            int affrows = await _fsql.Delete<Tool>().Where(t => t.Id == id).ExecuteAffrowsAsync();
            return RenderJson(data: affrows);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Update([FromForm] Tool tool) {
            int affrows = await _fsql.Update<Tool>().SetSourceIgnore(tool, colval => colval == null).ExecuteAffrowsAsync();
            return RenderJson(data: affrows);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Show([FromForm] long id) {
            Tool tool = await _fsql.Select<Tool>().Where(t => t.Id == id).ToOneAsync();
            return RenderJson(data: tool);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> GetCurrentUsedTools([FromForm] long bzgjid)
        {
            List<long> tids = await _fsql.Select<BaoZhangGongJuTools>().Where(bzgjt => bzgjt.Bzgjid == bzgjid).ToListAsync<long>(bzgjt => bzgjt.Tid);
            tids.Add(-1);
            List<Tool> tools = await _fsql.Select<Tool>().Where(t => tids.Contains(t.Id)).ToListAsync();
            return RenderJson(data: tools);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> GetNoUsedTools([FromForm] string content)
        {
            List<long> tids = await _fsql.Select<BaoZhangGongJuTools>().ToListAsync<long>(bzgjt => bzgjt.Tid);
            tids.Add(-1);
            DynamicFilterInfo dyfilter = JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
{
  'Logic' : 'And',
  'Filters' :
  [
    {
      'Field' : 'name',
      'Operator' : 'Contains',
      'Value' : '" + content + @"',
    }
  ]
}
");
            List<Tool> tools = await _fsql.Select<Tool>().Where(t => !tids.Contains(t.Id)).WhereDynamicFilter(dyfilter).ToListAsync();
            _logger.LogInformation(_fsql.Select<Tool>().Where(t => tids.Contains(t.Id)).ToSql());
            return RenderJson(data: tools);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> DownloadExcelTemplate()
        {
            IExcelExporter exporter = new ExcelExporter();
            var filePath = @"wwwroot/download/tool/工具库模板.xlsx";
            var arr = new[] { "工具名称", "工具型号", "规格" };
            var sheetName = "工具库";
            var result = await exporter.ExportHeaderAsByteArray(arr, sheetName);
            result.ToExcelExportFileInfo(filePath);
            JObject data = new();
            data.Add("url", _configuration.GetValue<string>("UploadUrl") + $"/download/tool/工具库模板.xlsx");
            return RenderJson(data: data);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> ExportExcel()
        {
            IExporter exporter = new ExcelExporter();
            var result = await exporter.Export(@"wwwroot/download/tool/工具库.xlsx", await _fsql.Select<Tool>().ToListAsync());

            JObject data = new();
            data.Add("url", _configuration.GetValue<string>("UploadUrl") + $"/download/tool/工具库.xlsx");
            return RenderJson(data: data);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> ImportExcel([FromForm] string filePath)
        {
            //filePath = @"upload/excel/工具库模板.xlsx";
            string webrootpath = _env.WebRootPath;
            FileInfo file = new FileInfo(Path.Combine(webrootpath, filePath));

            long affrows = 0;
            _fsql.Transaction(() => {
                try
                {
                    using (ExcelPackage package = new ExcelPackage(file))
                    {
                        ExcelWorksheet worksheet = package.Workbook.Worksheets.First();
                        int rowCount = worksheet.Dimension.Rows;
                        var items = new List<Tool>();
                        for (int row = 2; row <= rowCount; row++)
                        {
                            items.Add(new Tool { Name = worksheet.Cells[row, 1].Value?.ToString() ?? "", Xinghao = worksheet.Cells[row, 2].Value?.ToString() ?? "", Guige = worksheet.Cells[row, 3].Value?.ToString() ?? "" });
                        }
                        affrows = _fsql.Insert(items).ExecuteAffrows();
                    }
                }
                catch (Exception e)
                {
                    affrows = -1;
                    _logger.LogInformation("导入工具库失败：" + e.Message);
                }

            });
            if (affrows == -1)
            {
                return RenderJson(status: "failed", message: "导入工具库失败", code: -1);
            }
            return RenderJson(data: affrows);
        }
    }
}
